package org.bdware.irp.irpclient;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.ssl.SslHandler;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import org.apache.log4j.Logger;
import org.bdware.irp.irplib.core.IrpMessage;

import java.util.Random;

@ChannelHandler.Sharable
public class NettyIrpClientHandler extends SimpleChannelInboundHandler<IrpMessage>{

    static Logger logger = Logger.getLogger(NettyIrpClientHandler.class);
    public Channel channel;
    ResponseWait sync = new ResponseWait();
    Random random = new Random();

    public void sendMessage(IrpMessage request, IrpMessageCallback callback) {
        if (callback == null) {
            logger.error("DoMessageCallback is null, please check!");
        }
        //logger.debug("client handle sending message");

        if(request.envelope.requestId == 0){
            request.envelope.requestId = random.nextInt();
            while(!sync.waitResponse(request.envelope.requestId, callback)){
                request.envelope.requestId = random.nextInt();
            }
        }else{
            if(!sync.waitResponse(request.envelope.requestId, callback)){
                logger.debug("duplicate requestID, please check");
            }
        }
        //logger.debug("writeAndFlush: " + request.toString());
        logger.debug("channel status: " + channel.isActive());
        channel.writeAndFlush(request);
    }

    public void close() {
        channel.close();
    }

    public void setChannel(Channel c) {
        this.channel = c;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, IrpMessage msg){
        logger.debug("channelRead0 receive a message");
//        if (msg.body != null) logger.debug("body length :" + msg.body.length);
//        else logger.debug("body is null");
/*        if(msg.header.isCertified()){
            try {
                if(!CryptoUtils.verifyIrpMessage(msg)){
                    logger.warn("verification failed");
                    return;
                }
            }catch (Exception e){
                e.printStackTrace();
                return;
            }
        }*/
        sync.wakeUpAndRemove(msg.envelope.requestId, msg);
        ctx.close();
    }

/*    @Override
    public void channelActive(ChannelHandlerContext ctx) {
//        logger.debug("channel active");
        if(ctx.pipeline().get(SslHandler.class)!= null)
        ctx.pipeline().get(SslHandler.class).handshakeFuture().addListener(
            (GenericFutureListener<Future<Channel>>) future -> {
                if(future.isSuccess()){
                    logger.debug("TLS connection established");
                    SSLSession ss =  ctx.pipeline().get(SslHandler.class).engine().getSession();
                    X509Certificate cert = ss.getPeerCertificateChain()[0];
                    String info;
                    // 获得公钥编码
                    info = new String(cert.getPublicKey().getEncoded());
                    logger.debug("PublicKey:" + info);
                    // 获得证书主体信息
                    info = cert.getSubjectDN().getName();
                    logger.debug("Certification Owner:" + info);
                    // 获得证书颁发者信息
                    info = cert.getIssuerDN().getName();
                    logger.debug("Certification Issuer:" + info);
                    // 获得证书签名算法名称
                    info = cert.getSigAlgName();
                    logger.debug("Sign Algorithm:" + info);
                }else{
                    logger.info("TLS connection established failed");
                }
            });
    }*/

}
